package me.qixiaobo.config;

import lombok.extern.slf4j.Slf4j;
import me.qixiaobo.config.jackson.CustomerJsonSerializer;
import me.qixiaobo.config.jackson.JSON;
import me.qixiaobo.config.jackson.JSONS;
import me.qixiaobo.util.ResultModel;
import org.springframework.core.MethodParameter;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;

import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.Arrays;

/**
 * 返回数据统一处理
 *
 * @author guoyb
 * @date 2020/1/6
 */
@ControllerAdvice
@Slf4j
public class RestControllerResponseAdvice implements ResponseBodyAdvice<Object> {

    @Override
    public boolean supports(MethodParameter returnType, Class<? extends HttpMessageConverter<?>> converterType) {
        Method method = returnType.getMethod();
        JSON json = method.getAnnotation(JSON.class);
        JSONS jsons = method.getAnnotation(JSONS.class);
        if (json != null || jsons != null) {
            // 只处理含有JSON注解和jsons注解的方法
            return true;
        }
        return false;
    }

    @Override
    public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType,
                                  Class<? extends HttpMessageConverter<?>> selectedConverterType, ServerHttpRequest request,
                                  ServerHttpResponse response) {
        // 对body进行封装处理
        if (body instanceof ResultModel) {
            log.info("只处理含有JSON注解和jsons注解的方法-----打印日志------{}", request.getURI());

            // 获得注解并执行filter方法 最后返回
            Annotation[] annos = returnType.getMethodAnnotations();
            CustomerJsonSerializer jsonSerializer = new CustomerJsonSerializer();
            Arrays.asList(annos).forEach(a -> { // 解析注解，设置过滤条件
                if (a instanceof JSON) {
                    JSON json = (JSON) a;
                    jsonSerializer.filter(json);
                } else if (a instanceof JSONS) { // 使用多重注解时，实际返回的是 @Repeatable(JSONS.class) 内指定的 @JSONS 注解
                    JSONS jsons = (JSONS) a;
                    Arrays.asList(jsons.value()).forEach(json -> {
                        jsonSerializer.filter(json);
                    });
                }
            });

            ResultModel resultModel = null;
            try {
                return jsonSerializer.toJson(body);
            } catch (Exception e) {
                log.error("异常信息:{}", e.getMessage());
            }
            return resultModel;
        }
        return body;
    }
}